import { IHttpResponse, IParam } from '@/core/interface';
import { deepCopy, HttpResponse, UpperFirstLetter } from '@/core/utils';
import { ControlVOBase } from '../control-vo';
import { CtrlExServiceBase } from './ctrl-ex-service-base';

/**
 * 日历部件服务
 *
 * @class CalendarService
 */
class CalendarService<T extends ControlVOBase[]> extends CtrlExServiceBase<T> {
	constructor(controlVOTypes: IParam[], entityCodeName: string, opts?: IParam) {
		super(controlVOTypes, entityCodeName, opts);
		this.model = opts!.model;
		this.initEventsConfig();
	}

	/**
	 * 初始化日历项实体服务
	 *
	 * @memberof AppCalendarService
	 */
	public async initItemEntityService() {
		const calendarItems = this.model.calendarItems;
		if (calendarItems?.length > 0) {
			for (const item of calendarItems) {
				const entityCodeName = item.entityCodeName;
				if (entityCodeName) {
					const service: any = await App.getDataService(entityCodeName);
					this.entityServiceMap.set(entityCodeName, service);
				}
			}
		}
	}

	/**
	 * 事件配置集合
	 *
	 * @public
	 * @type {any[]}
	 * @memberof AppCalendarService
	 */
	public eventsConfig: IParam[] = [];

	/**
	 * 初始化事件配置集合
	 *
	 * @memberof AppCalendarService
	 */
	public initEventsConfig() {
		const tempArr: any[] = [];
		const calendarItems = this.model.calendarItems;
		if (calendarItems.length > 0) {
			calendarItems.forEach((item: IParam) => {
				tempArr.push({
					itemName: item.name,
					itemType: item.itemType,
					color: item.bKColor,
					textColor: item.color,
				});
			});
		}
		this.eventsConfig = [...tempArr];
	}

	public handleResponse(response: IHttpResponse, opts: any = {}) {
		if (!response.data) {
			return response;
		}
		let result = null;
		const itemType = opts.itemType;
		const UpperFirstItemType = UpperFirstLetter(itemType);
		const handleResult = (isCreate = false) => {
			if (response.data instanceof Array) {
				result = [];
				response.data.forEach((item: any, index: number) => {
					result.push(
						this.newControlVO(item, `${UpperFirstItemType}ControlVO`)
					);
				});
			} else {
				result = this.newControlVO(
					response.data,
					`${UpperFirstItemType}ControlVO`
				);
			}
			// response状态，头文件
			if (response.config) {
				if (response.config['x-page']) {
					Object.assign(response, { page: Number(response.config['x-page']) });
				}
				if (response.config['x-per-page']) {
					Object.assign(response, {
						size: Number(response.config['x-per-page']),
					});
				}
				if (response.config['x-total']) {
					Object.assign(response, {
						total: Number(response.config['x-total']),
					});
				}
			}
			response.data = result;
		};
		handleResult();
		return response;
	}

	async search(
		action: string,
		context: IParam = {},
		data: IParam = {}
	): Promise<IHttpResponse> {
		const _this = this;
		const calendarItems = this.model.calendarItems;
		if (calendarItems.length != _this.entityServiceMap.size) {
			await this.initItemEntityService();
		}
		return new Promise((resolve: any, reject: any) => {
			const promises: any[] = [];
			if (calendarItems.length > 0) {
				for (const item of calendarItems) {
					const codeName = item.entityCodeName;
					const service: any = _this.entityServiceMap.get(codeName);
					const tempRequest: any = _this.handleRequestData(context, data);
					Object.assign(tempRequest.data, { start: data.start, end: data.end });
					const appDeDataSet = item.dataSet;
					if (appDeDataSet.codeName && service) {
						promises.push(
							service[appDeDataSet.codeName](
								tempRequest.context,
								tempRequest.data
							)
						);
					}
				}
			}
			Promise.all(promises)
				.then((resArray: any) => {
					const _data: any = [];
					resArray.forEach((response: any, resIndex: number) => {
						if (!response.success) {
							return;
						}
						const _response: any = JSON.parse(JSON.stringify(response));
						_response.data.forEach((item: any, index: number) => {
							_response.data[index].color = _this.eventsConfig[resIndex].color;
							_response.data[index].textColor =
								_this.eventsConfig[resIndex].textColor;
							_response.data[index].itemType =
								_this.eventsConfig[resIndex].itemType;
							_response.data[index].curdata = deepCopy(item);
						});
						_this.handleResponse(_response, {
							itemType: _this.eventsConfig[resIndex]?.itemType,
						});
						_data.push(..._response.data);
					});
					resolve(new HttpResponse(_data));
				})
				.catch((response: any) => {
					reject(response);
				});
		});
	}
}
export default CalendarService;
